package org.biubiu0002.baiblog.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.biubiu0002.baiblog.common.constants.*;
import org.biubiu0002.baiblog.common.exception.BaiBlogException;
import org.biubiu0002.baiblog.common.exception.BizCodeEnumException;
import org.biubiu0002.baiblog.common.utils.PageQuery;
import org.biubiu0002.baiblog.common.utils.PageUtils;
import org.biubiu0002.baiblog.common.utils.Query;
import org.biubiu0002.baiblog.core.async.event.PostShareEvent;
import org.biubiu0002.baiblog.core.async.event.UpdateShareEvent;
import org.biubiu0002.baiblog.core.component.RabbitMqService;
import org.biubiu0002.baiblog.core.dao.ShareDao;
import org.biubiu0002.baiblog.core.model.dto.TokenUserDto;
import org.biubiu0002.baiblog.core.model.entity.*;
import org.biubiu0002.baiblog.core.model.vo.ShareVo;
import org.biubiu0002.baiblog.core.model.vo.UserInfoVo;
import org.biubiu0002.baiblog.core.model.vo.req.CommentReqVo;
import org.biubiu0002.baiblog.core.model.vo.req.SharePostReqVo;
import org.biubiu0002.baiblog.core.model.vo.res.*;
import org.biubiu0002.baiblog.core.service.*;
import org.biubiu0002.baiblog.core.utils.IdGenerator;
import org.biubiu0002.baiblog.core.utils.ImageUtils;
import org.biubiu0002.baiblog.core.utils.SecurityUtils;
import org.joda.time.DateTime;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service("shareService")
@Slf4j
public class ShareServiceImpl extends ServiceImpl<ShareDao, ShareEntity> implements ShareService {

    @Resource
    RichTextService richTextService;

    @Resource
    SysUserService sysUserService;

    @Resource
    ShareDao shareDao;

    @Resource
    LikeRecordService likeRecordService;

    @Resource
    CommentRecordService commentRecordService;

    @Resource
    ShareLikeCountService shareLikeCountService;

    @Resource
    ShareCommentCountService shareCommentCountService;

    @Resource
    ShareFavorCountService shareFavorCountService;

    @Resource
    FavorRecordService favorRecordService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RabbitMqService rabbitMqService;


    @Override
    public PageUtils queryIndexPage(Map<String, Object> params) {
        IPage<ShareEntity> page = this.page(
                new Query<ShareEntity>().getPage(params),
                new QueryWrapper<ShareEntity>()
                        .ne("share_post_status", 3)
                        .eq("status", 0)
                        .eq("is_deleted", 0)
                        .orderByDesc("create_time")
        );
        //分页获取记录
        List<ShareEntity> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            //分页结果为空
            return new PageUtils(page);
        }
        List<String> shareIdList = records.stream().map(ShareEntity::getResourceId).collect(Collectors.toList());
        List<ShareVo> itemsByShareIdList = this.getItemsByShareIdList(shareIdList);

        return new PageUtils(itemsByShareIdList, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());

    }

    @Transactional(rollbackFor = BaiBlogException.class)
    @Override
    public SharePostResVo postShare(SharePostReqVo sharePostReqVo) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.AUTHENTICATE_FAIL_EXCEPTION);
        }
        String userUid = user.getUserUid();
        String content = sharePostReqVo.getContent();
        SysUserEntity userByUserUid = sysUserService.getUserByUserUid(userUid);
        if (userByUserUid.getStatus() != 0) {
            throw new BaiBlogException(BizCodeEnumException.IN_BLACK_LIST_EXCEPTION);
        }
        List<String> imageUrls = sharePostReqVo.getImageUrls();
        ShareConstants.SharePostStatusEnum sharePostStatusEnum = sharePostReqVo.getSharePostStatusEnum();

        RichTextEntity richTextEntity = new RichTextEntity();
        if (!CollectionUtils.isEmpty(imageUrls)) {
            StringBuilder sb = new StringBuilder();
            imageUrls.forEach(item -> sb.append(item).append(","));
            sb.deleteCharAt(sb.length() - 1);
            String imageUrl = sb.toString();
            richTextEntity.setPhotoUrl(imageUrl);
        }

        //保存文本内容
        String shareId = IdGenerator.generateUid();
        String richTextId = IdGenerator.generateUid();
        richTextEntity.setContent(content);
        richTextEntity.setResourceId(richTextId);
        richTextEntity.setType(RichTextConstants.RichTextTypeEnum.SHARE.getCode());
        richTextEntity.setParentId(shareId);
        richTextEntity.setSharePostStatus(sharePostStatusEnum.getCode());
        richTextService.save(richTextEntity);
        //保存分享信息
        Date createTime = new Date();
        ShareEntity shareEntity = new ShareEntity();
        shareEntity.setResourceId(shareId);
        shareEntity.setTextId(richTextId);
        shareEntity.setUserUid(userUid);
        shareEntity.setCreateTime(createTime);
        shareEntity.setUpdateTime(createTime);
        shareEntity.setSharePostStatus(sharePostStatusEnum.getCode());
        this.baseMapper.insert(shareEntity);

        SharePostResVo sharePostResVo = new SharePostResVo();
        sharePostResVo.setShareId(shareId);
        sharePostResVo.setCreateTime(createTime);
        sharePostResVo.setUpdateTime(createTime);
        // info加入到缓存
        ShareInfoVo shareInfoVo = this.convertShareEntity2ShareInfoVo(shareEntity);
        redisTemplate.opsForValue().set(CacheConstants.getShareInfoKey(shareId), JSON.toJSONString(shareInfoVo));
        //发送mq
        PostShareEvent postShareEvent = new PostShareEvent(userUid, shareId,createTime.getTime());
        rabbitMqService.sendPostShareEvent(postShareEvent);
        return sharePostResVo;
    }

    @Override
    @Transactional(rollbackFor = BaiBlogException.class)
    public void likeShare(String shareId) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.AUTHENTICATE_FAIL_EXCEPTION);
        }
        if (!enableLikeShare(shareId)) {
            throw new BaiBlogException(BizCodeEnumException.UNABLE_LIKE_EXCEPTION);
        }

        String s = (String) redisTemplate.opsForHash().get(CacheConstants.getShareLikeMapKey(),
                CacheConstants.getUserShareField(user.getUserUid(), shareId));
        if (StringUtils.isBlank(s) || CacheConstants.FALSE.equals(s)) {
            //记录点赞情况
            redisTemplate.opsForHash().put(CacheConstants.getShareLikeMapKey(),
                    CacheConstants.getUserShareField(user.getUserUid(), shareId), CacheConstants.TRUE);
            //文章点赞数+1
            shareLikeCountService.incrementShareLikeCount(shareId);
            Integer shareLikeCount = shareLikeCountService.getShareLikeCount(shareId);
            //更新每周点赞榜
            redisTemplate.opsForZSet().add(CacheConstants.getWeeklyShareLikeCountBoardKey(), shareId, shareLikeCount);
        }
    }

    @Override
    @Transactional(rollbackFor = BaiBlogException.class)
    public void unLikeShare(String shareId) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.AUTHENTICATE_FAIL_EXCEPTION);
        }
        if (!enableLikeShare(shareId)) {
            throw new BaiBlogException(BizCodeEnumException.UNABLE_LIKE_EXCEPTION);
        }
        String s = (String) redisTemplate.opsForHash().get(CacheConstants.getShareLikeMapKey(),
                CacheConstants.getUserShareField(user.getUserUid(), shareId));
        if (StringUtils.isNotBlank(s) && CacheConstants.TRUE.equals(s)) {
            //设置点赞情况
            redisTemplate.opsForHash().put(CacheConstants.getShareLikeMapKey(),
                    CacheConstants.getUserShareField(user.getUserUid(), shareId), CacheConstants.FALSE);
            //点赞数-1
            shareLikeCountService.decrementShareLikeCount(shareId);
            //更新每周点赞榜
            redisTemplate.opsForZSet().incrementScore(CacheConstants.getWeeklyShareLikeCountBoardKey(), shareId, -1L);
        }
    }


    public PageUtils queryPage(Map<String, Object> params, String userId) {
        if(StringUtils.isBlank(userId)){
            throw new BaiBlogException(BizCodeEnumException.ILLEGAL_INPUT_EXCEPTION,"userId不能为空");
        }
        IPage<ShareEntity> page = this.page(new Query<ShareEntity>().getPage(params),
                new QueryWrapper<ShareEntity>()
                        .eq("user_uid", userId)
                        .eq("status", 0)
                        .eq("is_deleted", 0)
                        .orderByDesc("create_time")
        );
        //分页获取记录
        List<ShareEntity> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            //分页结果为空
            return new PageUtils(page);
        }
        List<String> shareIdList = records.stream().map(ShareEntity::getResourceId).collect(Collectors.toList());
        List<ShareVo> itemsByShareIdList = this.getItemsByShareIdList(shareIdList);

        return new PageUtils(itemsByShareIdList, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());

    }

    @Override
    public PageUtils queryMyPage(Map<String, Object> params) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.NOT_LOGIN_EXCEPTION);
        }
        String userUid = user.getUserUid();
        return queryPage(params, userUid);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommentPostResVo comment(String shareId, CommentReqVo commentReqVo) {
        TokenUserDto tokenUser = SecurityUtils.getUser();
        if (tokenUser == null) {
            throw new BaiBlogException(BizCodeEnumException.NOT_LOGIN_EXCEPTION);
        }
        if (!enableCommentShare(shareId)) {
            throw new BaiBlogException(BizCodeEnumException.UNABLE_COMMENT_EXCEPTION);
        }
        ShareEntity shareEntity = baseMapper.selectOne(new QueryWrapper<ShareEntity>()
                .eq("resource_id", shareId)
                .eq("status", 0)
                .eq("is_deleted", 0));
        if (shareEntity == null) {
            throw new BaiBlogException(BizCodeEnumException.SHARE_NOT_EXIST_EXCEPTION);
        }

        String textId = IdGenerator.generateUid();
        String commentId = IdGenerator.generateUid();
        String content = commentReqVo.getContent();
        RichTextEntity richTextEntity = new RichTextEntity();
        richTextEntity.setId(IdGenerator.generateId());
        richTextEntity.setResourceId(textId);
        richTextEntity.setContent(content);
        richTextEntity.setType(RichTextConstants.RichTextTypeEnum.COMMENT.getCode());
        richTextEntity.setParentId(commentId);
        richTextService.save(richTextEntity);
        CommentRecordEntity commentRecordEntity = new CommentRecordEntity();
        commentRecordEntity.setId(IdGenerator.generateId());
        commentRecordEntity.setResourceId(commentId);
        commentRecordEntity.setRootId(shareEntity.getResourceId());
        commentRecordEntity.setUserUid(tokenUser.getUserUid());
        commentRecordEntity.setCommentedId(shareId);
        commentRecordEntity.setCommentedType(CommentConstants.CommentedTypeEnum.SHARE.getCode());
        commentRecordEntity.setTextId(textId);
        commentRecordService.save(commentRecordEntity);
        //评论数+1
        redisTemplate.opsForValue().increment(CacheConstants.getShareCommentCountKey(commentRecordEntity.getRootId()));

        CommentPostResVo commentPostResVo = new CommentPostResVo();
        commentPostResVo.setCommentId(commentId);
        commentPostResVo.setCreateTime(new Date());
        return commentPostResVo;

    }

    @Override
    public CommentPostResVo reply(String commentedId, CommentReqVo commentReqVo) {
        TokenUserDto tokenUser = SecurityUtils.getUser();
        if (tokenUser == null) {
            throw new BaiBlogException(BizCodeEnumException.NOT_LOGIN_EXCEPTION);
        }
        CommentRecordEntity commentRecordServiceOne = commentRecordService.getOne(new QueryWrapper<CommentRecordEntity>()
                .eq("resource_id", commentedId).eq("is_deleted", 0));
        if (commentRecordServiceOne == null) {
            throw new BaiBlogException(BizCodeEnumException.COMMENT_NOT_EXIST_EXCEPTION);
        }
        String textId = IdGenerator.generateUid();
        String commentId = IdGenerator.generateUid();
        String content = commentReqVo.getContent();
        RichTextEntity richTextEntity = new RichTextEntity();
        richTextEntity.setId(IdGenerator.generateId());
        richTextEntity.setResourceId(textId);
        richTextEntity.setContent(content);
        richTextEntity.setType(RichTextConstants.RichTextTypeEnum.COMMENT.getCode());
        richTextEntity.setParentId(commentId);
        richTextService.save(richTextEntity);
        CommentRecordEntity commentRecordEntity = new CommentRecordEntity();
        commentRecordEntity.setId(IdGenerator.generateId());
        commentRecordEntity.setResourceId(IdGenerator.generateUid());
        commentRecordEntity.setRootId(commentRecordServiceOne.getRootId());
        commentRecordEntity.setCommentedId(commentedId);
        commentRecordEntity.setUserUid(tokenUser.getUserUid());
        commentRecordEntity.setCommentedType(CommentConstants.CommentedTypeEnum.COMMENT.getCode());
        commentRecordEntity.setTextId(textId);
        commentRecordService.save(commentRecordEntity);
        //评论数+1
        redisTemplate.opsForValue().increment(CacheConstants.getShareCommentCountKey(commentRecordEntity.getRootId()));
        CommentPostResVo commentPostResVo = new CommentPostResVo();
        commentPostResVo.setCommentId(commentId);
        commentPostResVo.setCreateTime(new Date());
        return commentPostResVo;
    }

    @Override
    public PageUtils queryMyFavorPage(Map<String, Object> params) {
        //直接查数据库
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.NOT_LOGIN_EXCEPTION);
        }
        IPage<FavorRecordEntity> page = favorRecordService.page(new Query<FavorRecordEntity>().getPage(params),
                new QueryWrapper<FavorRecordEntity>()
                        .eq("user_uid", user.getUserUid())
                        .eq("is_favor", 1)
                        .eq("is_deleted", 0)
                        .orderByDesc("create_time")
        );
        //分页获取记录
        List<FavorRecordEntity> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            //分页结果为空
            return new PageUtils(page);
        }
        List<String> shareIdList = records.stream().map(FavorRecordEntity::getShareId).collect(Collectors.toList());
        List<ShareVo> itemsByShareIdList = this.getItemsByShareIdList(shareIdList);
        return new PageUtils(itemsByShareIdList, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());

    }

    @Override
    @Transactional(rollbackFor = BaiBlogException.class)
    public void favorShare(String shareId) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.NOT_LOGIN_EXCEPTION);
        }
        ShareEntity shareEntity = this.getByShareId(shareId);
        if (shareEntity == null) {
            throw new BaiBlogException(BizCodeEnumException.RECORD_NOT_EXIST_EXCEPTION);
        }
        if (!enableFavorShare(shareId)) {
            throw new BaiBlogException(BizCodeEnumException.UNABLE_FAVOR_EXCEPTION);
        }

        String userUid = user.getUserUid();
        //判断收藏情况
        Boolean hasKey = redisTemplate.hasKey(CacheConstants.getShareUserFavorKey(userUid));
        //用户收藏key失效
        if (Boolean.FALSE.equals(hasKey)) {
            favorRecordService.loadFromDB2Redis(userUid);
        }

        Boolean isMember = redisTemplate.opsForSet().isMember(CacheConstants.getShareUserFavorKey(userUid), shareId);
        //不在收藏set中
        if (Boolean.FALSE.equals(isMember)) {
            //处理收藏关系
            favorRecordService.favorShare(userUid, shareId);
            //缓存数+1
            redisTemplate.opsForValue().increment(CacheConstants.getShareFavorCountKey(shareId));
        }


    }

    @Override
    public void unFavorShare(String shareId) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.NOT_LOGIN_EXCEPTION);
        }
        ShareEntity shareEntity = this.getByShareId(shareId);
        if (shareEntity == null) {
            throw new BaiBlogException(BizCodeEnumException.RECORD_NOT_EXIST_EXCEPTION);
        }
        if (!enableFavorShare(shareId)) {
            throw new BaiBlogException(BizCodeEnumException.UNABLE_FAVOR_EXCEPTION);
        }
        String userUid = user.getUserUid();
        //判断收藏情况
        Boolean hasKey = redisTemplate.hasKey(CacheConstants.getShareUserFavorKey(userUid));
        //用户key失效
        if (Boolean.FALSE.equals(hasKey)) {
            favorRecordService.loadFromDB2Redis(userUid);
        }

        Boolean isMember = redisTemplate.opsForSet().isMember(CacheConstants.getShareUserFavorKey(userUid), shareId);
        //在收藏set中
        if (Boolean.TRUE.equals(isMember)) {
            //处理收藏关系
            favorRecordService.unFavorShare(userUid, shareId);
            //缓存数-1
            redisTemplate.opsForValue().decrement(CacheConstants.getShareFavorCountKey(shareId));
        }

    }

    @Override
    public ShareEntity getByShareId(String shareId) {
        return baseMapper.selectOne(new QueryWrapper<ShareEntity>()
                .eq("resource_id", shareId)
                .eq("status", 0)
                .eq("is_deleted", 0)
        );

    }

    @Override
    public ShareEntity getByShareIdAll(String shareId) {
        return baseMapper.selectOne(new QueryWrapper<ShareEntity>()
                .eq("resource_id", shareId)
                .eq("is_deleted", 0)
        );
    }

    @Override
    @Transactional(rollbackFor = BaiBlogException.class)
    public SharePostResVo updateShare(String shareId, SharePostReqVo sharePostReqVo) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.NOT_LOGIN_EXCEPTION);
        }
        ShareEntity shareEntity = this.getByShareId(shareId);
        if (shareEntity == null) {
            throw new BaiBlogException(BizCodeEnumException.RECORD_NOT_EXIST_EXCEPTION, "分享记录不存在");
        }
        if (!shareEntity.getUserUid().equals(user.getUserUid())) {
            //修改不是自己发布的内容
            throw new BaiBlogException(BizCodeEnumException.AUTHENTICATE_FAIL_EXCEPTION);
        }
        Preconditions.checkArgument(sharePostReqVo.getSharePostStatusEnum()!=null,"推文可见状态不能为空");
        String textId = shareEntity.getTextId();
        RichTextEntity richTextEntity = richTextService.getByTextId(textId);
        //修改文本内容
        if (!StringUtils.equals(richTextEntity.getContent(), sharePostReqVo.getContent())) {
            richTextEntity.setContent(sharePostReqVo.getContent());
        }
        String richTextImageUrl = ImageUtils.convertImagesUrlList2Url(sharePostReqVo.getImageUrls());
        //修改图片内容
        if (!StringUtils.equals(richTextImageUrl, richTextEntity.getPhotoUrl())) {
            richTextEntity.setPhotoUrl(richTextImageUrl);
        }
        shareEntity.setSharePostStatus(sharePostReqVo.getSharePostStatusEnum().getCode());
        //文本表也需要记录推文可见状态
        richTextEntity.setSharePostStatus(sharePostReqVo.getSharePostStatusEnum().getCode());
        richTextService.updateById(richTextEntity);

        Date updateTime = new Date();
        shareEntity.setUpdateTime(updateTime);
        //更新数据库
        this.updateById(shareEntity);

        //更新前的shareInfoVo
        ShareInfoVo oldShareInfoVo = this.getShareInfoVoByShareId(shareId);
        //删除redis中key 保证数据一致性
        //删除基本信息key
        redisTemplate.delete(CacheConstants.getShareInfoKey(shareId));
        //删除榜单信息key
        redisTemplate.delete(CacheConstants.getShareBoardItemKey(shareId));
        //更新后的shareInfoVo 删后写 相当于update
        ShareInfoVo newShareInfoVo = this.getShareInfoVoByShareId(shareId);

        SharePostResVo sharePostResVo = new SharePostResVo();
        sharePostResVo.setShareId(shareId);
        sharePostResVo.setCreateTime(shareEntity.getCreateTime());
        sharePostResVo.setUpdateTime(updateTime);
        //发送mq
        UpdateShareEvent updateShareEvent = new UpdateShareEvent(oldShareInfoVo, newShareInfoVo);
        rabbitMqService.sendUpdateShareEvent(updateShareEvent);

        return sharePostResVo;

    }

    @Override
    public void updateShareStatus(String shareId, Integer status) {
        shareDao.updateShareStatus(shareId, status);
    }

    @Override
    public void updateShareListStatus(List<String> shareIdList, Integer status) {
        if (CollectionUtils.isEmpty(shareIdList)) {
            throw new BaiBlogException(BizCodeEnumException.INNER_INPUT_EXCEPTION, "传入集合不能为空");
        }
        shareDao.updateShareListStatus(shareIdList, status);
    }

    @Override
    public List<ShareEntity> getShareListByUserUid(String userUid) {
        return this.list(new QueryWrapper<ShareEntity>()
                .eq("user_uid", userUid)
                .eq("status", 0)
                .eq("is_deleted", 0)
        );
    }

    @Override
    public List<ShareEntity> getShareListByUserUidAll(String userUid) {
        return this.list(new QueryWrapper<ShareEntity>()
                .eq("user_uid", userUid)
                .eq("is_deleted", 0)
        );
    }

    @Override
    public List<ShareEntity> getShareAllListByUserUid(String userUid) {
        return this.list(new QueryWrapper<ShareEntity>()
                .eq("user_uid", userUid)
                .eq("is_deleted", 0)
                .orderByDesc("create_time")
        );
    }

    @Override
    public PageUtils searchPage(Map<String, Object> params) {
        PageQuery<RichTextEntity> queryPage = new PageQuery<>(params);
        String key = (String) params.get("key");
        Preconditions.checkArgument(StringUtils.isNotBlank(key), "搜索关键字不能为空");
        Preconditions.checkArgument(key.length() <= 50, "搜索关键字不能超过50");
        IPage<RichTextEntity> richTextEntityIPage = richTextService.searchPage(key, TextConstants.ContentTypeEnum.SHARE.getValue(), queryPage);
        List<RichTextEntity> richTextEntityList = richTextEntityIPage.getRecords();
        List<String> collect = richTextEntityList.stream().map(RichTextEntity::getParentId).collect(Collectors.toList());
        List<ShareVo> itemsByShareIdList = getItemsByShareIdList(collect);
        PageUtils pageUtils = new PageUtils(richTextEntityIPage);
        pageUtils.setList(itemsByShareIdList);
        return pageUtils;
    }

    @Override
    @Transactional(rollbackFor = BaiBlogException.class)
    public void deleteShare(String shareId) {
        TokenUserDto user = SecurityUtils.getUser();
        if (user == null) {
            throw new BaiBlogException(BizCodeEnumException.AUTHENTICATE_FAIL_EXCEPTION);
        }
        ShareEntity shareEntity = getByShareId(shareId);
        if (shareEntity == null) {
            throw new BaiBlogException(BizCodeEnumException.RECORD_NOT_EXIST_EXCEPTION, "分享记录不存在");
        }
        if (!StringUtils.equals(shareEntity.getUserUid(), user.getUserUid())) {
            throw new BaiBlogException(BizCodeEnumException.AUTHORIZE_FAIL_EXCEPTION);
        }
        doDeleteShare(shareId);

    }

    private void doDeleteShare(String shareId) {
        if (StringUtils.isBlank(shareId)) {
            throw new BaiBlogException(BizCodeEnumException.INNER_INPUT_EXCEPTION);
        }
        //1.更新数据库
        this.updateShareStatus(shareId, ShareConstants.ShareStatusEnum.DELETED.getValue());
        richTextService.updateShareTextStatus(Collections.singletonList(shareId), ShareConstants.ShareStatusEnum.DELETED.getValue());
        //2.删除缓存
        String shareInfoKey = CacheConstants.getShareInfoKey(shareId);
        String shareLikeCountKey = CacheConstants.getShareLikeCountKey(shareId);
        String shareCommentCountKey = CacheConstants.getShareCommentCountKey(shareId);
        String shareFavorCountKey = CacheConstants.getShareFavorCountKey(shareId);
        redisTemplate.delete(Arrays.asList(shareInfoKey,shareLikeCountKey,shareCommentCountKey,shareFavorCountKey));
        //3.删除榜单数据
        this.removeFromLikeCountBoard(shareId);
        this.removeFromLatestBoard(shareId);

    }

    @Override
    public PageUtils queryCommentsPage(String shareId, Map<String, Object> params) {
        IPage<CommentRecordEntity> page = commentRecordService.page(
                new Query<CommentRecordEntity>().getPage(params),
                new QueryWrapper<CommentRecordEntity>()
                        .eq("commented_id", shareId)
                        .eq("comment_status",0)
                        .eq("is_deleted", 0)
                        .orderByDesc("create_time")
        );

        List<CommentRecordEntity> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return new PageUtils(page);
        }
        Map<String, CommentRecordEntity> commentIdCommentMap = records.stream().collect(Collectors.toMap(CommentRecordEntity::getResourceId, e -> e, (oldV, newV) -> newV));
        List<String> commentIdList = records.stream().map(CommentRecordEntity::getResourceId).collect(Collectors.toList());
        List<String> userUidList = records.stream().map(CommentRecordEntity::getUserUid).collect(Collectors.toList());
        List<String> commentTextIdList = records.stream().map(CommentRecordEntity::getTextId).collect(Collectors.toList());
        Map<String, UserInfoVo> userInfoMap = sysUserService.getUserInfoMap(userUidList);
        Map<String, RichTextEntity> richTextEntityMap = richTextService.getRichTextEntityMap(commentTextIdList);
        List<CommentResVo> result = new ArrayList<>(10);

        for (String commentId : commentIdList) {
            CommentRecordEntity entity = commentIdCommentMap.get(commentId);
            UserInfoVo userInfoVo = userInfoMap.get(entity.getUserUid());
            RichTextEntity richTextEntity = richTextEntityMap.get(entity.getTextId());

            Map<String, Object> childParams = new HashMap<>(2);
            childParams.put("page", "1");
            childParams.put("limit", "2");
            IPage<CommentRecordEntity> commentPage = commentRecordService.page(new Query<CommentRecordEntity>().getPage(childParams),
                    new QueryWrapper<CommentRecordEntity>()
                            .eq("commented_id", commentId)
                            .eq("comment_status",0)
                            .eq("is_deleted", 0)
                            .orderByDesc("create_time")
            );
            long childTotal = commentPage.getTotal();
            //2条缩略记录
            List<CommentRecordEntity> reply = commentPage.getRecords();
            List<CommentResVo> childCommentResVoList = new ArrayList<>(2);
            if (!CollectionUtils.isEmpty(reply)) {
                List<String> childUserUidList = reply.stream().map(CommentRecordEntity::getUserUid).collect(Collectors.toList());
                List<String> childCommentTextIdList = reply.stream().map(CommentRecordEntity::getTextId).collect(Collectors.toList());
                Map<String, UserInfoVo> childUserInfoMap = sysUserService.getUserInfoMap(childUserUidList);
                Map<String, RichTextEntity> childRichTextEntityMap = richTextService.getRichTextEntityMap(childCommentTextIdList);
                childCommentResVoList = reply.stream().map(childRecordEntity -> {
                    String childCommentId = childRecordEntity.getResourceId();
                    CommentResVo commentResVo = new CommentResVo();
                    UserInfoVo childUserInfo = childUserInfoMap.get(childRecordEntity.getUserUid());
                    RichTextEntity childRichTextEntity = childRichTextEntityMap.get(childRecordEntity.getTextId());
                    commentResVo.setCommentId(childCommentId);
                    commentResVo.setCreateTime(childRecordEntity.getCreateTime());
                    commentResVo.setNickname(childUserInfo.getNickname());
                    commentResVo.setContent(childRichTextEntity.getContent());
                    return commentResVo;
                }).collect(Collectors.toList());
            }


            CommentResVo commentResVo = new CommentResVo();
            commentResVo.setCommentId(commentId);
            commentResVo.setNickname(userInfoVo.getNickname());
            commentResVo.setAvatar(userInfoVo.getAvatar());
            commentResVo.setContent(richTextEntity.getContent());
            commentResVo.setReply(childCommentResVoList);
            commentResVo.setTotal((int) childTotal);
            commentResVo.setCreateTime(entity.getCreateTime());
            result.add(commentResVo);
        }

        //暴力循环查库
        //对每个评论分页查询得到2条数据
        //输入 commentIdList
        //输出 评论了commentId对应的id 按时间降序 返回2条 ,回复了commentId的回复数量
        return new PageUtils(result, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

    @Override
    public void recoverFromLikeCountBoard(String shareId) {
        //恢复到点赞周榜
        Integer shareLikeCount = shareLikeCountService.getShareLikeCount(shareId);
        ShareInfoVo shareInfoVo = this.getShareInfoVoByShareId(shareId);
        //推文创建时间
        Date createTime = shareInfoVo.getCreateTime();
        //当前时间
        DateTime now = DateTime.now();
        Date date = now.toDate();
        //这周榜单清洗时间
        Date thisCleanDate = now.withDayOfWeek(1).withHourOfDay(4).withMinuteOfHour(30).withSecondOfMinute(0).toDate();
        //上周榜单清洗时间
        Calendar c = Calendar.getInstance();
        c.setTime(thisCleanDate);
        c.add(Calendar.DATE, -7);
        Date lastCleanDate = c.getTime();
        if (canRecoverFromLikeCountBoard(shareLikeCount, createTime, date, thisCleanDate, lastCleanDate)) {
            redisTemplate.opsForZSet().add(CacheConstants.getWeeklyShareLikeCountBoardKey(), shareId, shareLikeCount);
        }
    }

    /**
     * 点赞数>0
     * 当前时间小于本周一 创建时间大于上周一才加入到榜单
     * 当前时间大于本周一 创建时间大于本周一才加入到榜单
     *
     * @param shareLikeCount 点赞数
     * @param createTime     创建时间
     * @param date           当前时间
     * @param thisCleanDate  这周一清洗时间
     * @param lastCleanDate  上周一清洗时间
     * @return 是否加入榜单
     */
    private boolean canRecoverFromLikeCountBoard(Integer shareLikeCount, Date createTime, Date date, Date thisCleanDate, Date lastCleanDate) {
        return shareLikeCount > 0 && (date.before(thisCleanDate) && createTime.after(lastCleanDate)
                || date.after(thisCleanDate) && createTime.after(thisCleanDate));
    }


    @Override
    public void removeFromLikeCountBoard(String shareId) {
        redisTemplate.opsForZSet().remove(CacheConstants.getWeeklyShareLikeCountBoardKey(), shareId);
    }

    @Override
    public List<ShareBoardItemVo> getLikeCountBoard() {
        Set<ZSetOperations.TypedTuple<String>> typedTuples = redisTemplate.opsForZSet().reverseRangeByScoreWithScores(CacheConstants.getWeeklyShareLikeCountBoardKey(), 0L, 9L);
        if (CollectionUtils.isEmpty(typedTuples)) {
            return Collections.emptyList();
        }
        List<String> shareIdList = typedTuples.stream().map(ZSetOperations.TypedTuple::getValue).collect(Collectors.toList());
        Map<String, ShareBoardItemVo> shareBoardItemVoMap = this.getShareBoardItemVoMap(shareIdList);
        Iterator<ZSetOperations.TypedTuple<String>> iterator = typedTuples.iterator();
        List<ShareBoardItemVo> res = new ArrayList<>();
        int rank = 1;
        while (iterator.hasNext()) {
            ZSetOperations.TypedTuple<String> next = iterator.next();
            String shareId = next.getValue();
            Double likeCount = next.getScore();
            ShareBoardItemVo shareBoardItemVo = shareBoardItemVoMap.get(shareId);
            if (shareBoardItemVo == null) {
                continue;
            }
            shareBoardItemVo.setRank(rank++);
            shareBoardItemVo.setScore(likeCount);
            res.add(shareBoardItemVo);
        }

        return res;
    }

    public Map<String, ShareBoardItemVo> getShareBoardItemVoMap(List<String> shareIdList) {
        if (CollectionUtils.isEmpty(shareIdList)) {
            return Collections.emptyMap();
        }
        return shareIdList.stream().map(this::getShareBoardItemVoByShareId)
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(ShareBoardItemVo::getShareId, e -> e, (oldV, newV) -> newV));

    }

    @Override
    public Map<String, ShareBoardItemVo> getShareLikeCountBoardItemVoMap(List<String> shareIdList) {
        if (CollectionUtils.isEmpty(shareIdList)) {
            return Collections.emptyMap();
        }
        //先读缓存
        Map<String, ShareBoardItemVo> res = new HashMap<>(shareIdList.size());
        List<String> redisNotExistedShareIdList = new ArrayList<>();
        for (String shareId : shareIdList) {
            String itemJson = redisTemplate.opsForValue().get(CacheConstants.getShareBoardItemKey(shareId));
            if (StringUtils.isNotBlank(itemJson)) {
                res.put(shareId, JSON.parseObject(itemJson, ShareBoardItemVo.class));
            } else {
                //缓存中不存在
                redisNotExistedShareIdList.add(shareId);

            }
        }
        if (!CollectionUtils.isEmpty(redisNotExistedShareIdList)) {
            //从db读 写到redis设置超时时间
            List<ShareEntity> list = this.list(new QueryWrapper<ShareEntity>()
                    .in("resource_id", shareIdList)
                    .eq("is_deleted", 0)
            );
            List<String> textIdList = list.stream().map(ShareEntity::getTextId).collect(Collectors.toList());
            List<RichTextEntity> richTextEntities = new ArrayList<>();

            if (!CollectionUtils.isEmpty(textIdList)) {
                richTextEntities = richTextService.list(new QueryWrapper<RichTextEntity>()
                        .in("resource_id", textIdList)
                        .eq("is_deleted", 0)
                );
            }


            Map<String, RichTextEntity> textIdTextMap = richTextEntities.stream().collect(Collectors.toMap(RichTextEntity::getResourceId, e -> e, (oldV, newV) -> newV));

            Map<String, ShareBoardItemVo> shareBoardItemInfoFromDB = list.stream().collect(Collectors.toMap(ShareEntity::getResourceId, item -> {
                RichTextEntity richTextEntity = textIdTextMap.get(item.getTextId());
                if (richTextEntity == null) {
                    return null;
                }
                ShareBoardItemVo shareBoardItemVo = new ShareBoardItemVo();
                shareBoardItemVo.setShareId(item.getResourceId());
                shareBoardItemVo.setContent(richTextEntity.getContent());
                List<String> images = this.convertImagesUrl2UrlList(richTextEntity.getPhotoUrl());
                if (!images.isEmpty()) {
                    shareBoardItemVo.setImage(images.get(0));
                }
                return shareBoardItemVo;

            }, (oldV, newV) -> newV));

            res.putAll(shareBoardItemInfoFromDB);

            //写回redis
            shareBoardItemInfoFromDB.forEach((shareId, info) -> {
                redisTemplate.opsForValue().set(CacheConstants.getShareBoardItemKey(shareId), JSON.toJSONString(info),
                        CacheConstants.getShareLikeCountBoardItemExpireMinutes(), TimeUnit.MINUTES);
            });
        }
        return res;
    }

    @Override
    public void insertIntoLatestBoard(String shareId) {
        ShareInfoVo shareInfoVo = this.getShareInfoVoByShareId(shareId);
        if (shareInfoVo == null) {
            return;
        }
        if (shareInfoVo.getSharePostStatus() != null && shareInfoVo.getSharePostStatus() == ShareConstants.SharePostStatusEnum.NO_VIEW.getCode()) {
            return;
        }
        //添加到最新发布榜
        redisTemplate.opsForList().leftPush(CacheConstants.getShareLatestBoardKey(), shareId);
        Long size = redisTemplate.opsForList().size(CacheConstants.getShareLatestBoardKey());
        if (size != null && size > 10) {
            redisTemplate.opsForList().trim(CacheConstants.getShareLatestBoardKey(), 0, 9);
        }
    }

    @Override
    public void recoverFromLatestBoard(String shareId) {
        //目前的数据结构就决定了无法直接找回发布前的时间 只能挨个排序
        ShareInfoVo shareInfoVo = this.getShareInfoVoByShareId(shareId);
        Date createTime = shareInfoVo.getCreateTime();
        List<String> shareIdList = redisTemplate.opsForList().range(CacheConstants.getShareLatestBoardKey(), 0, -1);
        if (CollectionUtils.isEmpty(shareIdList)) {
            this.insertIntoLatestBoard(shareId);
            return;
        }
        //排序 插入到对应日期位置
        Map<Date, String> dateShareIdMap = shareIdList.stream().map(this::getShareInfoVoByShareId)
                .collect(Collectors.toMap(ShareInfoVo::getCreateTime, ShareInfoVo::getShareId, (oldV, newV) -> newV));

        List<Date> dateList = dateShareIdMap.keySet().stream().sorted((o1, o2) -> o2.compareTo(o1)).collect(Collectors.toList());
        for (int i = 0; i < dateList.size(); i++) {
            Date date = dateList.get(i);
            if (createTime.compareTo(date) > 0) {
                //找到比这个时间大的第一个元素 插入
                redisTemplate.opsForList().leftPush(CacheConstants.getShareLatestBoardKey(), dateShareIdMap.get(dateList.get(i)), shareId);
                Long size = redisTemplate.opsForList().size(CacheConstants.getShareLatestBoardKey());
                if (size != null && size > 10) {
                    redisTemplate.opsForList().trim(CacheConstants.getShareLatestBoardKey(), 0, 9);
                }
                return;
            }
        }
    }

    @Override
    public void removeFromLatestBoard(String shareId) {
        //从左到右第一个与shareId一致的元素
        redisTemplate.opsForList().remove(CacheConstants.getShareLatestBoardKey(), 1, shareId);
    }

    @Override
    public List<ShareBoardItemVo> getLatestBoard() {
        List<String> latestShareIdList = redisTemplate.opsForList().range(CacheConstants.getShareLatestBoardKey(), 0, 9);
        if (CollectionUtils.isEmpty(latestShareIdList)) {
            return Collections.emptyList();
        }
        int i = 1;
        List<ShareBoardItemVo> res = new ArrayList<>(latestShareIdList.size());
        for (String shareId : latestShareIdList) {
            ShareBoardItemVo shareBoardItemVo = getShareBoardItemVoByShareId(shareId);
            if (shareBoardItemVo == null) {
                continue;
            }
            shareBoardItemVo.setRank(i++);
            res.add(shareBoardItemVo);
        }
        return res;
    }

    @Override
    public PageUtils queryRepliesPage(String commentedId, Map<String, Object> params) {
        IPage<CommentRecordEntity> page = commentRecordService.page(new Query<CommentRecordEntity>().getPage(params),
                new QueryWrapper<CommentRecordEntity>()
                        .eq("commented_id", commentedId)
                        .eq("comment_status",0)
                        .eq("is_deleted", 0)
                        .orderByDesc("create_time")
        );
        List<CommentRecordEntity> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageUtils(page);
        }
        List<String> userUidList = records.stream().map(CommentRecordEntity::getUserUid).collect(Collectors.toList());
        List<String> textIdList = records.stream().map(CommentRecordEntity::getTextId).collect(Collectors.toList());
        Map<String, UserInfoVo> userInfoMap = sysUserService.getUserInfoMap(userUidList);
        Map<String, RichTextEntity> richTextEntityMap = richTextService.getRichTextEntityMap(textIdList);
        List<CommentResVo> collect = records.stream().map(record -> {
            UserInfoVo userInfoVo = userInfoMap.get(record.getUserUid());
            RichTextEntity richTextEntity = richTextEntityMap.get(record.getTextId());
            CommentResVo commentResVo = new CommentResVo();
            commentResVo.setCommentId(record.getResourceId());
            commentResVo.setNickname(userInfoVo.getNickname());
            commentResVo.setCreateTime(record.getCreateTime());
            commentResVo.setContent(richTextEntity.getContent());
            return commentResVo;
        }).collect(Collectors.toList());
        return new PageUtils(collect, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

    @Override
    public ShareInfoVo getShareInfoVoByShareId(String shareId) {
        String shareInfoJson = redisTemplate.opsForValue().get(CacheConstants.getShareInfoKey(shareId));
        if (StringUtils.isBlank(shareInfoJson)) {
            //缓存不存在 从db读 写到缓存 并设置超时时间
            //考虑缓存击穿 设置分布式锁
            RLock lock = redissonClient.getLock(CacheConstants.getShareInfoLock(shareId));
            try {
                lock.lock();
                ShareEntity shareEntity = this.getByShareId(shareId);
                if(shareEntity==null){
                    //设置空缓存
                    return null;
                }
                //查出包括被拉黑的文章
//                ShareEntity shareEntity = this.getByShareIdAll(shareId);
                ShareInfoVo shareInfoVo = this.convertShareEntity2ShareInfoVo(shareEntity);
                shareInfoJson = JSON.toJSONString(shareInfoVo);
                //设置到redis缓存
                redisTemplate.opsForValue().set(CacheConstants.getShareInfoKey(shareId), shareInfoJson,
                        CacheConstants.getUserInfoExpireMinutes(), TimeUnit.MINUTES);
                return shareInfoVo;

            } catch (Exception e) {
                log.error("获取分布式锁，从db加载shareInfo失败");
            } finally {
                lock.unlock();
            }
        }
        //获取分布式锁失败 shareInfoJson仍为null或空
        if (StringUtils.isBlank(shareInfoJson)) {
            return null;
        }
        //缓存命中 缓存更新 反序列化后返回
        return JSON.parseObject(shareInfoJson, ShareInfoVo.class);
    }

    @Override
    public List<ShareInfoVo> getInfoListByShareIdList(List<String> shareIdList) {
        if (CollectionUtils.isEmpty(shareIdList)) {
            return Collections.emptyList();
        }
        return shareIdList.stream().map(this::getShareInfoVoByShareId).filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    @Override
    public ShareVo getItemByShareId(String shareId) {
        TokenUserDto user = SecurityUtils.getUser();
        if (!enableViewShare(shareId)) {
            throw new BaiBlogException(BizCodeEnumException.UNABLE_VIEW_EXCEPTION);
        }
        return getItemByShareId(shareId, user);
    }

    public ShareVo getItemByShareId(String shareId, TokenUserDto user) {
        ShareInfoVo shareInfoVo = this.getShareInfoVoByShareId(shareId);
        if (shareInfoVo == null) {
            return null;
        }
        ShareVo shareVo = new ShareVo();
        BeanUtils.copyProperties(shareInfoVo, shareVo);
        shareVo.setLikeCount(shareLikeCountService.getShareLikeCount(shareId));
        shareVo.setCommentCount(shareCommentCountService.getShareCommentCount(shareId));
        shareVo.setFavorCount(shareFavorCountService.getShareFavorCount(shareId));
        if (user == null) {
            shareVo.setIsLike(false);
            shareVo.setIsFavor(false);
        } else {
            String userUid = user.getUserUid();
            shareVo.setIsLike(likeRecordService.isUserLikeShare(userUid, shareId));
            shareVo.setIsFavor(favorRecordService.isUserFavorShare(userUid, shareId));
        }
        return shareVo;

    }


    @Override
    public List<ShareVo> getItemsByShareIdList(List<String> shareIdList) {
        if (CollectionUtils.isEmpty(shareIdList)) {
            return Collections.emptyList();
        }
        TokenUserDto user = SecurityUtils.getUser();
        return shareIdList.stream().map(shareId -> this.getItemByShareId(shareId, user)).filter(Objects::nonNull)
                .collect(Collectors.toList());
    }


    private List<String> convertImagesUrl2UrlList(String imagesUrl) {
        if (StringUtils.isBlank(imagesUrl)) {
            return Collections.emptyList();
        }
        return Arrays.asList(imagesUrl.split(","));

    }

    private boolean enableLikeShare(String shareId) {
        String shareInfoVoJson = redisTemplate.opsForValue().get(CacheConstants.getShareInfoKey(shareId));
        if(StringUtils.isBlank(shareInfoVoJson)){
            return false;
        }
        ShareInfoVo shareInfoVo = JSON.parseObject(shareInfoVoJson, ShareInfoVo.class);
        Integer sharePostStatus = shareInfoVo.getSharePostStatus();
        if (sharePostStatus == null) {
            return true;
        }
        if (sharePostStatus == ShareConstants.SharePostStatusEnum.ALLOW.getCode() ||
                sharePostStatus == ShareConstants.SharePostStatusEnum.CANT_COMMENT.getCode()) {
            return true;
        }
        return false;
    }

    private boolean enableCommentShare(String shareId) {
        String shareInfoVoJson = redisTemplate.opsForValue().get(CacheConstants.getShareInfoKey(shareId));
        if(StringUtils.isBlank(shareInfoVoJson)){
            return false;
        }
        ShareInfoVo shareInfoVo = JSON.parseObject(shareInfoVoJson, ShareInfoVo.class);
        Integer sharePostStatus = shareInfoVo.getSharePostStatus();
        if (sharePostStatus == null) {
            return true;
        }
        if (sharePostStatus == ShareConstants.SharePostStatusEnum.ALLOW.getCode()) {
            return true;
        }
        return false;
    }

    private boolean enableFavorShare(String shareId) {
        return enableCommentShare(shareId);
    }

    private boolean enableViewShare(String shareId) {
        String shareInfoVoJson = redisTemplate.opsForValue().get(CacheConstants.getShareInfoKey(shareId));
        if(StringUtils.isBlank(shareInfoVoJson)){
            return false;
        }
        ShareInfoVo shareInfoVo = JSON.parseObject(shareInfoVoJson, ShareInfoVo.class);
        Integer sharePostStatus = shareInfoVo.getSharePostStatus();
        if (sharePostStatus == null) {
            return true;
        }
        if (sharePostStatus.equals(ShareConstants.SharePostStatusEnum.NO_VIEW.getCode())) {
            TokenUserDto user = SecurityUtils.getUser();
            if (user == null) {
                return false;
            }
            String userUid = user.getUserUid();
            ShareEntity byShareId = getByShareId(shareId);
            if (!StringUtils.equals(byShareId.getUserUid(), userUid)) {
                return false;
            }
        }
        return true;
    }

    public ShareInfoVo convertShareEntity2ShareInfoVo(ShareEntity shareEntity) {
        if (shareEntity == null) {
            return null;
        }
        if(shareEntity.getStatus()!=null&&shareEntity.getStatus()!=0){
            return null;
        }
        String shareId = shareEntity.getResourceId();
        String textId = shareEntity.getTextId();
        String userUid = shareEntity.getUserUid();
        ShareInfoVo shareInfoVo = new ShareInfoVo();
        Map<String, UserInfoVo> userInfoMap = sysUserService.getUserInfoMap(Collections.singletonList(userUid));
        UserInfoVo userInfoVo = userInfoMap.get(userUid);
        RichTextEntity richTextEntity = richTextService.getByTextId(textId);
        if(richTextEntity==null){
            return null;
        }
        shareInfoVo.setShareId(shareId);
        shareInfoVo.setUserUid(userInfoVo.getUserUid());
        shareInfoVo.setNickname(userInfoVo.getNickname());
        shareInfoVo.setAvatar(userInfoVo.getAvatar());
        shareInfoVo.setImages(ImageUtils.convertImagesUrl2UrlList(richTextEntity.getPhotoUrl()));
        shareInfoVo.setContent(richTextEntity.getContent());
        shareInfoVo.setSharePostStatus(shareEntity.getSharePostStatus());
        shareInfoVo.setCreateTime(shareEntity.getCreateTime());
        shareInfoVo.setUpdateTime(shareEntity.getUpdateTime());
        return shareInfoVo;
    }


    public ShareBoardItemVo getShareBoardItemVoByShareId(String shareId) {
        ShareInfoVo shareInfoVo = this.getShareInfoVoByShareId(shareId);
        if (shareInfoVo.getSharePostStatus() != null && shareInfoVo.getSharePostStatus() == ShareConstants.SharePostStatusEnum.NO_VIEW.getCode()) {
            return null;
        }
        ShareBoardItemVo shareBoardItemVo = new ShareBoardItemVo();
        BeanUtils.copyProperties(shareInfoVo, shareBoardItemVo);
        if (!CollectionUtils.isEmpty(shareInfoVo.getImages())) {
            shareBoardItemVo.setImage(shareInfoVo.getImages().get(0));
        }
        shareBoardItemVo.setContent(shareInfoVo.getContent());
        shareBoardItemVo.setCreateTime(shareInfoVo.getCreateTime());
        return shareBoardItemVo;
    }

    @Override
    public List<ShareEntity> loadFeedByFollowsByCreateTime(List<String> followList,Long timestamp) {
        if(CollectionUtils.isEmpty(followList)){
            return Collections.emptyList();
        }
        if(timestamp==null){
            throw new BaiBlogException(BizCodeEnumException.INNER_INPUT_EXCEPTION);
        }
        List<ShareEntity> shareEntities = shareDao.loadFeedByFollowsByCreateTime(followList, timestamp);
        if(CollectionUtils.isEmpty(shareEntities)){
            return Collections.emptyList();
        }
        return shareEntities;
    }



}